import { KeyboardEvent } from 'react';
import { Validate, ValidateRule } from '../types';
import { tagStyleOptions } from './defaultData';
import regionData from './region.json';
import { Message } from '@arco-design/web-react';
import dayjs from 'dayjs';

/**
 * 随机字符串 默认32位
 * @param len 需要的长度
 * @returns string
 */
export function randomString(len?: number) {
  len = len || 32;
  let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678oOLl9gqVvUuI1';
  let maxPos = $chars.length;
  let pwd = '';
  for (let i = 0; i < len; i++) {
    pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
  }
  return pwd;
}

/**
 * 延时休眠
 * @param ms 毫秒
 * @returns Promise<void>
 */
export function delay(ms: number) {
  return new Promise<void>((resolve, reject) => {
    setTimeout(() => {
      resolve();
    }, ms);
  });
}

/**
 * 清除对象内的空Key
 * @param _p 数据
 * @returns 数据
 */
export function clearEmptyKey(params: any) {
  let _p = cloneDeep(params);
  Object.keys(_p).forEach((i) => {
    if (!_p[i]) {
      delete _p[i];
    } else if (typeof _p[i] === 'object') {
      if (_p[i] instanceof Object) {
        _p[i] = clearEmptyKey(_p[i]);
      }
      if (!Object.keys(_p[i]).length) {
        delete _p[i];
      }
    }
  });
  return _p;
}

/**
 * 把对象的Key按字典排序并转成字符串
 * @param obj 数据
 * @returns string
 */
export function objectSortToString(obj: any): string {
  if (obj === undefined || obj === null) return '';
  if (typeof obj === 'string') return 'str:' + obj;
  if (typeof obj === 'boolean') return 'bool:' + obj.toString();
  if (typeof obj === 'number') return 'num:' + obj.toString();
  let keys = Object.keys(obj);
  if (!keys.length) return '{}';
  keys.sort();
  let map: any = {};
  for (let key of keys) {
    let s = objectSortToString(obj[key]);
    map[key] = s;
  }
  return JSON.stringify(map);
}

/**
 * 参数对比 看是否值相等
 * @param obj1
 * @param obj2
 * @returns boolean
 */
export function compareParams(obj1: any, obj2: any): boolean {
  if ((!obj1 && obj2) || (obj1 && !obj2)) return false;
  let str1 = objectSortToString(clearEmptyKey(obj1));
  let str2 = objectSortToString(clearEmptyKey(obj2));
  return str1 === str2;
}

// tag 颜色转换
export function findTagColor(color?: string) {
  if (!color) return '';
  let v = tagStyleOptions.find((i) => i.value === color);
  if (v) return v.value;
  if (color === 'processing') return 'arcoblue';
  if (color === 'info') return 'cyan';
  if (color === 'danger') return 'red';
  return 'arcoblue';
}

// 字段规则验证
export function validateField(data: any, rules: ValidateRule) {
  const numberReg = /^\d+(.\d+)?$/;
  let map: { [x: string]: any } = {};
  let fields: string[] = Object.keys(rules);

  for (let field of fields) {
    let _rule = rules[field];
    let validateData = (data ?? {})[field];
    if (typeof _rule === 'boolean') {
      // 检测到 _obj:true 本项不处理
      continue;
    }

    if (typeof _rule !== 'string' && _rule._obj) {
      let _map = validateField(validateData, _rule as ValidateRule);
      if (Object.keys(_map).length) {
        _map._obj = true;
        map[field] = _map;
      }
      continue;
    }

    let rule: Validate = _rule as Validate;
    let mastCheck = false;
    if (typeof rule.required === 'string') {
      // 依赖于 某个字段等于某个值 可以用`逗号[,]`分割多个字段，只要有一个依赖字段的值符合并且自身为空 就显示错误
      // 依赖于 某个字段等于某个值 可以用`和号[&]`分割多个字段，需要全部的依赖字段的值符合并且自身为空 就显示错误
      if (rule.required.includes(',')) {
        let requiredFields = rule.required.split(',');
        for (let requiredField of requiredFields) {
          // 如果依赖字段的值是包含逗号分割的多个值，则只要符合其中一项且自身为空，就显示错误
          if (rule[requiredField].includes(',')) {
            for (let requiredFieldValue of rule[requiredField].split(',')) {
              if (data[requiredField] === requiredFieldValue) {
                mastCheck = true;
                break;
              }
            }
          } else if (data[requiredField] === rule[requiredField]) {
            mastCheck = true;
          }
        }
      } else if (rule.required.includes('&')) {
        mastCheck = true;
        let requiredFields = rule.required.split('&');
        for (let requiredField of requiredFields) {
          // 如果依赖字段的值是包含逗号分割的多个值，则只要符合其中一项且自身为空，就显示错误
          if (rule[requiredField].includes(',')) {
            for (let requiredFieldValue of rule[requiredField].split(',')) {
              if (data[requiredField] === requiredFieldValue) {
                mastCheck = true;
                break;
              }
            }
          } else if (data[requiredField] !== rule[requiredField]) {
            mastCheck = false;
          }
        }
      } else {
        // 如果依赖字段的值是包含逗号分割的多个值，则只要符合其中一项且自身为空，就显示错误
        if (rule[rule.required].includes(',')) {
          for (let requiredFieldValue of rule[rule.required].split(',')) {
            if (data[rule.required] === requiredFieldValue) {
              mastCheck = true;
              break;
            }
          }
        } else if (data[rule.required] === rule[rule.required]) {
          mastCheck = true;
        }
      }
    } else if (typeof rule.required === 'boolean' && rule.required) {
      mastCheck = true;
    }

    if (!!validateData || mastCheck) {
      if (rule.bool === true) {
        if (validateData !== true && validateData !== false) {
          map[field] = rule.message;
        }
      } else if (rule.number === true) {
        if ((!validateData && validateData !== 0) || !numberReg.test(validateData)) {
          map[field] = rule.message;
        }
      } else if (rule.min || rule.min === 0) {
        if (validateData * 1 < rule.min!) {
          map[field] = rule.message;
        }
      } else if (rule.max || rule.max === 0) {
        if (validateData * 1 > rule.max!) {
          map[field] = rule.message;
        }
      } else if (rule.minLength || rule.minLength === 0) {
        if ((validateData + '').length < rule.minLength) {
          map[field] = rule.message;
        }
      } else if (rule.maxLength || rule.maxLength === 0) {
        if ((validateData + '').length > rule.maxLength) {
          map[field] = rule.message;
        }
      } else if (rule.regexp) {
        if (!rule.regexp!.test(validateData)) {
          map[field] = rule.message;
        }
      } else if (!validateData) {
        map[field] = rule.message;
      }
    }
  }
  return map;
}

// 解析路由参数 转成对象
export function parseQueryParams(path: string) {
  let p = path.startsWith('?') ? path.substring(1) : path;
  let list = p.split('&');
  let map: { [x: string]: any } = {};
  list.forEach((i) => {
    let [k, v] = i.split('=');
    map[k] = v;
  });
  return map;
}

// 省份列表
export function provinceList(all?: boolean): string[] {
  let _list = regionData.map((i) => i.label);
  if (all) {
    _list.unshift('全国');
  }
  return _list;
}
// 城市列表
export function cityList(province?: string): string[] {
  if (province) {
    let _province = regionData.find((i) => i.label === province);
    if (_province) {
      return _province.children.map((i) => i.label);
    }
  }
  let _list: string[] = [];
  regionData.forEach((i) => {
    _list = _list.concat(i.children.map((c) => c.label));
  });
  return _list;
}
// 县/区列表
export function areaList(province?: string, city?: string): string[] {
  let _province = regionData.find((i) => i.label === province);
  if (province && _province) {
    let _city = _province.children.find((c) => c.label === city);
    if (city && _city) {
      return _city.children.map((a) => a.label);
    } else {
      let _list: string[] = [];
      _province.children.forEach((c) => {
        _list = _list.concat(c.children.map((a) => a.label));
      });
      return _list;
    }
  }
  let _list: string[] = [];
  regionData.forEach((i) => {
    i.children.forEach((c) => {
      _list = _list.concat(c.children.map((a) => a.label));
    });
  });
  return _list;
}

// 深拷贝
export function cloneDeep(obj: any) {
  if (typeof obj !== 'object') return obj;
  return JSON.parse(JSON.stringify(obj));
}

// 基本类型数组 去重
export function clearRepeat(list: Array<string | number>) {
  let _tmp: Array<string | number> = [];
  for (let i of list) {
    if (!_tmp.includes(i)) {
      _tmp.push(i);
    }
  }
  return _tmp;
}

/** 基本类型数组 去空 */
export function clearEmpty(list: Array<string | number>) {
  let _tmp: Array<string | number> = [];
  for (let i of list) {
    if (!!i && i !== 'undefined' && i !== 'null' && i !== 'NaN' && i.toString().length > 0) {
      _tmp.push(i);
    }
  }
  return _tmp;
}

/**
 * 把一个json类型的字符串格式化成带换行和错位的字符串
 * ! 允许不符合格式的json
 * ! 但前置空位会错乱
 */
export function stringJsonFormat(s: string) {
  let tmp = s;
  if (tmp.includes('{}')) {
    tmp = tmp.split('{}').join('~');
  }
  if (tmp.includes('[]')) {
    tmp = tmp.split('[]').join('·');
  }
  if (tmp.includes('{')) {
    tmp = tmp.split('{').join('{\n');
  }
  if (tmp.includes('}')) {
    tmp = tmp.split('}').join('\n}');
  }
  if (tmp.includes('[')) {
    tmp = tmp.split('[').join('[\n');
  }
  if (tmp.includes(']')) {
    tmp = tmp.split(']').join('\n]');
  }
  if (tmp.includes(',')) {
    tmp = tmp.split(',').join(',\n');
  }

  if (tmp.includes(':[')) {
    tmp = tmp.split(':[').join(':\n[');
  }
  if (tmp.includes(': [')) {
    tmp = tmp.split(': [').join(':\n[');
  }
  if (tmp.includes(':{')) {
    tmp = tmp.split(':{').join(':\n{');
  }
  if (tmp.includes(': {')) {
    tmp = tmp.split(': {').join(':\n{');
  }
  if (tmp.includes('~')) {
    tmp = tmp.split('~').join('{}');
  }
  if (tmp.includes('·')) {
    tmp = tmp.split('·').join('[]');
  }
  let space = 0;
  let list = tmp.split('\n');
  let tlist: string[] = [];
  let pre = '';
  for (let s of list) {
    if (/^[[{]/.test(s.trim())) {
      if (pre === '{') space += 1;
      if (pre === '}') space += 0;
      if (pre === '') space += 1;
      pre = '{';
    } else if (/^[\]}]/.test(s.trim())) {
      if (pre === '{') space += 0;
      if (pre === '}') space -= 1;
      if (pre === '') space -= 1;
      pre = '}';
    } else {
      if (pre === '{') space += 1;
      if (pre === '}') space -= 1;
      if (pre === '') space -= 0;
      pre = '';
    }
    var tspace = '';
    for (var i = 0; i < space; i++) {
      tspace += '  ';
    }
    s = tspace + s.trim();
    if (s.trim()) {
      tlist.push(s);
    }
  }
  tmp = tlist.join('\n');
  return tmp;
}

// 流量转换 K -> T
export function flowKTOT(v?: number) {
  if ((v ?? 0) === 0) return 0;
  return v! / 1024 / 1024 / 1024;
}
// 流量转换 K -> G
export function flowKTOG(v?: number) {
  if ((v ?? 0) === 0) return 0;
  return v! / 1024 / 1024;
}

// 流量转换 G -> K
export function flowGTOK(v?: number) {
  if ((v ?? 0) === 0) return 0;
  return v! * 1024 * 1024;
}

// 回车执行方法 防止连点1秒
let t = 0;
export function onKeyEnter(onKeyEnter: Function) {
  return (event: KeyboardEvent<HTMLInputElement>) => {
    if (event.key === 'Enter') {
      let nowTime = new Date().getTime();
      if (nowTime - t < 1000) {
        t = nowTime;
        return;
      }
      t = nowTime;
      onKeyEnter();
    }
  };
}

// 防止连点
export function disableContinuousClick(onClick: Function) {
  return () => {
    let nowTime = new Date().getTime();
    if (nowTime - t < 1000) {
      t = nowTime;
      Message.warning('请不要连点');
      return;
    }
    t = nowTime;
    onClick();
  };
}

/**
 * 创建一个新的对象并排除参数里的属性
 */
export function omitObject(obj: { [x: string]: any }, args: string[]) {
  let _newObj: any = {};
  Object.keys(obj).forEach((k) => {
    if (!args.includes(k)) {
      _newObj[k] = obj[k];
    }
  });
  return _newObj;
}

/**
 * 格式化数字为以逗号分割的字符串
 * @param num 要格式化的数字
 * @param precision 数字精度
 * @returns 格式化后的字符串
 */
export function formatNumber(num?: string | number, precision?: number) {
  let isNegative = parseFloat((num ?? 0).toString()) < 0;
  let t: string = Math.abs(parseFloat((num ?? 0).toString())).toFixed(precision ?? 2);
  let _list = t.split('.');
  let _format = '';
  for (let i = _list[0].length - 1; i >= 0; i--) {
    if (_format.length > 0 && _format.replaceAll(',', '').length % 3 === 0) {
      _format = ',' + _format;
    }
    _format = _list[0][i] + _format;
  }
  _list[0] = _format;
  let res = _list.join('.');
  if (res.startsWith(',')) {
    res = res.substring(1);
  }
  return (isNegative ? '-' : '') + res;
}

/**
 * 获取当前时间转换成叙述句
 */
export function beforeTime(time: Date | string) {
  let currentTime = dayjs();
  let targetTime = dayjs(time);
  let diff = Math.abs(currentTime.diff(targetTime, 'second'));
  if (targetTime.isBefore(currentTime.subtract(1, 'day').startOf('day'))) {
    if (targetTime.year() === currentTime.year()) {
      return targetTime.format('MM-DD HH:mm');
    }
    return targetTime.format('YYYY-MM-DD HH:mm:ss');
  } else if (targetTime.isBefore(currentTime.startOf('day'))) {
    return '昨天 ' + targetTime.format('HH:mm:ss');
  } else if (diff < 50) {
    return '刚刚';
  } else if (diff < 60 * 2) {
    return '1分钟前';
  } else if (diff < 60 * 60 * 1) {
    return Math.floor(diff / 60) + '分钟前';
  } else if (diff < 60 * 60 * 12) {
    return Math.floor(diff / 60 / 60) + '小时前';
  } else if (diff < 60 * 60 * 24) {
    return targetTime.format('HH:mm:ss');
  } else {
    return targetTime.format('YYYY-MM-DD HH:mm:ss');
  }
}
/**
 * 格式化时间差 转成 mm:ss
 * @param startTime
 * @param endTime
 * @returns
 */
export function diffTimeFormat(startTime: string, endTime: string) {
  let diff = dayjs(startTime).diff(dayjs(endTime), 'second');
  let m = Math.floor(diff / 60);
  let s = diff % 60;
  let mm = m < 10 ? '0' + m : m;
  let ss = s < 10 ? '0' + s : s;
  return mm + ':' + ss;
}

export function formatFileSize(size: number) {
  let sizeStr = '';
  if (size < 1024) {
    sizeStr = size + 'B';
  } else if (size < 1024 * 1024) {
    sizeStr = formatNumber(size / 1024) + 'KB';
  } else if (size < 1024 * 1024 * 1024) {
    sizeStr = formatNumber(size / 1024 / 1024) + 'MB';
  } else {
    sizeStr = formatNumber(size / 1024 / 1024 / 1024) + 'GB';
  }
  return sizeStr;
}

/** 任意分割的字符串转换成逗号分割的字符串 */
export function replaceString(str: string) {
  let t = str
    .replaceAll('\n', ',')
    .replaceAll(';', ',')
    .replaceAll('，', ',')
    .replaceAll('；', ',')
    .replaceAll('、', ',')
    .replaceAll(' ', ',')
    .replaceAll(/,+/g, ',');
  if (t.endsWith(',')) {
    t = t.substring(0, t.length - 1);
  }
  if (t.startsWith(',')) {
    t = t.substring(1);
  }
  if (t === ',') {
    t = '';
  }
  return t;
}

/**
 * 解析json字符串
 * @param str 字符串
 * @param isArray 是否是数组
 * @returns
 */
export function jsonParse(str?: string, isArray?: boolean) {
  if (!str) return isArray ? [] : {};
  try {
    return JSON.parse(str);
  } catch (e) {
    return isArray ? [] : {};
  }
}

/**
 * 解析html字符串
 * @param htmlString html字符串
 * @returns 解析后的字符串
 */
export function htmlParse(htmlString?: string) {
  // 创建一个 DOMParser 实例
  const parser = new DOMParser();
  // 解析 HTML 字符串为一个文档对象
  const doc = parser.parseFromString(htmlString ?? '', 'text/html');
  // 获取文档的 body 元素的文本内容
  const textContent = doc.body.textContent;
  return textContent;
}
